﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Objects.DataClasses;
using System.Data;
using System.Linq.Expressions;
using SemPlayGen.DataModel;

namespace SemPlayGen.Repository
{
    public abstract class BaseRepository<T> : IRepository<T> where T: EntityObject
    {
        public virtual bool Insert(T entity)
        {
            if (entity == null)
                return false;

            try
            {
                var context = CreateContext();
                context.AddObject(this.GetEntitySetName(context), entity);
                context.SaveChanges();

                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public virtual bool Update(T entity)
        {
            var ctx = CreateContext();

            object originalEntity;
            EntityKey key = ctx.CreateEntityKey(this.GetEntitySetName(ctx), entity);

            if (ctx.TryGetObjectByKey(key, out originalEntity))
            {
                ctx.ApplyCurrentValues(key.EntitySetName, entity);
                ctx.SaveChanges();
                return true;
            }
            return false;
        }

        public virtual bool Delete(T entity)
        {
            var ctx = CreateContext();

            object originalEntity;
            EntityKey key = ctx.CreateEntityKey(this.GetEntitySetName(ctx), entity);

            if (ctx.TryGetObjectByKey(key, out originalEntity))
            {
                ctx.DeleteObject(originalEntity);
                ctx.SaveChanges();
                return true;
            }
            return false;
        }

        public virtual T GetSingle(Expression<Func<T, bool>> whereCondition)
        {
            var ctx = CreateContext();

            T entity = ctx.CreateObjectSet<T>().Where(whereCondition).FirstOrDefault();
            return entity;
        }

        public IEnumerable<T> GetAll<TKeyType>(Expression<Func<T, TKeyType>> keySortingSelector, SortingMode sortingMode)
        {
            var ctx = CreateContext();
            var objectSet = ctx.CreateObjectSet<T>();

            if (sortingMode == SortingMode.ascending)
                return objectSet.OrderBy(keySortingSelector);
            else
                return objectSet.OrderByDescending(keySortingSelector);
        }

        public IEnumerable<T> FindAll<TKeyType>(Expression<Func<T, bool>> whereCondition, Expression<Func<T, TKeyType>> keySortingSelector, SortingMode sortingMode)
        {
            var ctx = CreateContext();
            var objectSet = ctx.CreateObjectSet<T>().Where(whereCondition);

            if (sortingMode == SortingMode.ascending)
                return objectSet.OrderBy(keySortingSelector);
            else
                return objectSet.OrderByDescending(keySortingSelector);
        }





        protected SemPlayGenEntities CreateContext()
        {
            return ObjectContextCreator.Create();
        }

        protected internal string GetEntitySetName(SemPlayGenEntities context)
        {
            return context.DefaultContainerName + "." + typeof(T).Name; //context.CreateObjectSet<T>().EntitySet.Name;
        }

    }
}